___________________________________________________________________________ __________________________________________________________________ /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\ | Descriptions des fichiers xxx.d3-posi faites par Luc Billard || | et légèrement annotées par Frédéric Lançon ( novembre 1999). || ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' Fichier xxxxx-posi.d3 --------------------- Un fichier xxxxx-posi.d3 est un fichier décrivant une succession de configurations atomiques d'un alliage. Ce fichier doit avoir une structure particulière qui a été définie originellement par F. LANÇON, et est créé par une écriture Fortran sous la forme non formattée : spécificateur FORM = 'UNFORMATTED' dans l'instruction OPEN. De façon à assurer une portabilité entre les machines qui utilisent des conventions différentes pour l'écriture interne des données, nous imposons ici une spécification supplémentaire : les données doivent être écrites selon la convention 'big endian'; c'est la convention par défaut sur les machines Sun, mais ce n'est pas la convention par défaut sur les machines DEC. Donc, si vous créez un fichier xxxxx.d3 par un programme Fortran qui s'exécute sur DEC, vous devez : - soit compiler ce programme avec l'option -convert big_endian - soit utiliser l'extension DEC au Fortran 90 qui permet le spécificateur CONVERT = 'BIG_ENDIAN' dans l'instruction OPEN. Structure du fichier xxxxx-posi.d3. (Rappel: chaque instruction Fortran WRITE écrit 1 et 1 seul enregistrement) Le fichier xxxxx-posi.d3 est constitué de la répétition en nombre indéterminé de blocs décrivant une configuration et formés de 8 enregistrements du type suivant: 1er enregistrement: TITRE CHARACTER*128 TITRE : chaîne de 128 caractères 2ème enregistrement: NPAS, TEMPS INTEGER*4 NPAS : numéro REAL*8 TEMPS : valeur du temps (ces deux paramètres ne sont ici qu'à titre indicatif, et ne servent pas dans la description subséquente) 3ème enregistrement: NAT, NTYPE INTEGER*4 NAT : nombre d'atomes INTEGER*4 NTYPE : nombre de types d'atomes 4ème enregistrement: (NATI(I), I = 1, NTYPE), (NOM(I), I = 1, NTYPE) INTEGER*4 NATI(*) : nombre d'atomes de chacun des types 1...NTYPE CHARACTER*8 NOM(*) : noms des types 1...NTYPE 5ème enregistrement: DXX, DYX, DYY, DZX, DZY, DZZ REAL*8 DXX, DYX, DYY, DZX, DZY, DZZ : taille et forme de la boite La boîte parallèlépipédique étant définie par 3 vecteurs a, b et c, on appelle : DXX : projection sur X du vecteur a. DYX : projection sur X du vecteur b. DYY : projection sur Y du vecteur b. DZX : projection sur X du vecteur c. DZY : projection sur Y du vecteur c. DZZ : projection sur Z du vecteur c. 6ème enregistrement: (X(I), I = 1, NAT) REAL*4 X(*) : coordonnées X des atomes (les atomes sont rangés de sorte que les NATI(1) 1ers sont du type 1, les NATI(2) suivants sont du type 2, etc... ATTENTION : X est REAL*4 7ème enregistrement: (Y(I), I = 1, NAT) REAL*4 Y(*) : coordonnées Y des atomes ATTENTION : Y est REAL*4 8ème enregistrement: (Z(I), I = 1, NAT) coordonnées Z des atomes ATTENTION : Z est REAL*4 Exemple: program posi ! ATTENTION : pour compiler sur DEC, utiliser l'option : ! -convert big_endian ! construction d'un fichier xxxxx-posi.d3 implicit none ! chaine de 128 caractères laissée à l'appréciation de l'utilisateur character(len = 128) :: titre ! numéro du pas integer :: npas ! et temps à ce pas real(kind = 8) :: temps ! nombre d'atomes et nombre de types d'atomes integer :: nat, ntype ! nombres d'atomes de chacun des types integer, dimension(:), allocatable :: nati ! et noms de chacun des types character(len = 8), dimension(:), allocatable :: nom ! dimensions de la boite real(kind = 8) :: dxx, dyx, dyy, dzx, dzy, dzz ! coordonnées des atomes ! ATTENTION kind = 4 real(kind = 4), dimension(:), allocatable :: x, y, z integer :: m, n, i, j, k real(kind = 8) :: xx, yy, zz, xdel, ydel, zdel character(len = 128) ifich integer, parameter :: unit = 10 ! note: ! dans le cas présenté ici, tous les fichiers ! de l'enregistrement ont les mêmes caractéristiques ! et ne diffèrent que par les valeurs des coordonnées ! mais ce n'est pas nécessaire; par exemple, ! nous modifions le titre à chaque pas ! nombre d'atomes; exemple: nat = 36 ! et nombre de types d'atomes; exemple: ntype = 2 ! allocation des tableaux allocate(nati(ntype)) if (.not. allocated(nati)) then write(*, *) 'Cannot allocate nati' stop endif allocate(nom(ntype)) if (.not. allocated(nom)) then write(*, *) 'Cannot allocate nom' stop endif allocate(x(nat)) if (.not. allocated(nom)) then write(*, *) 'Cannot allocate x' stop endif allocate(y(nat)) if (.not. allocated(nom)) then write(*, *) 'Cannot allocate y' stop endif allocate(z(nat)) if (.not. allocated(nom)) then write(*, *) 'Cannot allocate z' stop endif ! nombres d'atomes de chacun des types; exemple: nati(1) = 18 nati(2) = 18 ! et noms de chacun des types; exemple: nom(1) = 'atomes A' nom(2) = 'atomes B' ! dimensions de la boite; exemple: dxx = 3.d0 dyx = 0.d0 dyy = 3.d0 dzx = 0.d0 dzy = 0.d0 dzz = 4.d0 ! nom du fichier ifich = 'toto.d3' open(unit, file = ifich, form = 'unformatted', action = 'write') ! pour écrire les résultats sur la console, ! dé-commenter les lignes suivantes ! write(*, '(A, A)') 'fichier:', trim(ifich) ! boucle sur les npas fichiers; exemple npas = 5 boucle: do m = 1, npas xdel = +0.01d0*m ydel = -0.02d0*m zdel = -0.03d0*m ! titre; exemple: write(titre, '(A, I3)') 'fichier au pas ', m ! npas et temps npas = m temps = m * 1.d-13 ! écriture du fichier (début) write(unit) titre write(unit) npas, temps write(unit) nat, ntype write(unit) nati, nom write(unit) dxx, dyx, dyy, dzx, dzy, dzz ! coordonnées des atomes ! d'abord les nati(1) atomes de type nom(1) n = 0 do i = 1, 3 xx = -0.5d0 + dble(i) + xdel do j = 1, 3 yy = -0.5d0 + dble(j) + ydel do k = 1, 4, 2 zz = -0.5d0 + dble(k) + zdel n = n + 1 x(n) = real(xx) y(n) = real(yy) z(n) = real(zz) end do end do end do if ( n /= nati(1)) then write(*, *) 'erreur sur nati(1)' stop endif nati(1) = n do i = 1, 3 xx = -0.5d0 + dble(i) - xdel do j = 1, 3 yy = -0.5d0 + dble(j) - ydel do k = 2, 4, 2 zz = -0.5d0 + dble(k) - zdel n = n + 1 x(n) = real(xx) y(n) = real(yy) z(n) = real(zz) end do end do end do if ( n /= nat) then write(*, *) 'erreur sur nat' stop endif ! note: je ne vérifie pas que j'ai bien mis les atomes ! à l'intérieur de la boite!..... ! écriture du fichier (suite) write(unit) x write(unit) y write(unit) z ! pour écrire les résultats sur la console, ! dé-commenter les lignes suivantes ! write(*, '(A, A)') 'titre=', trim(titre) ! write(*, '(A, I3, A, F12.4)') 'npas=', npas, ' temps=', temps ! write(*, '(A, I3, A, I2)') 'nat=', nat, ' et ntype=', ntype ! write(*, '(I3, A, A)') & ! (nati(n), ' atomes appelés ', nom(n), n = 1, ntype) ! write(*, '(A, F10.3, /, & ! & A, F10.3, A, F10.3, /, & ! & A, F10.3, A, F10.3, A, F10.3)') & ! 'dxx=', dxx, & ! 'dyx=', dyx, ' dyy=', dyy, & ! 'dzx=', dzx, ' dzy=', dzy, ' dzz=', dzz ! write(*, '(I3, 1X, F10.3, 5X, F10.3, 5X, F10.3)') & ! (n, x(n), y(n), z(n), n = 1, nat) end do boucle close(unit) end program posi ###############################################################################